﻿using Microsoft.Xaml.Interactivity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;

namespace App4.Behaviors
{
    class NullableCheckboxBehavior : DependencyObject, IBehavior
    {
        public Windows.UI.Xaml.DependencyObject AssociatedObject { get; set; }

        public void Attach(Windows.UI.Xaml.DependencyObject associatedObject)
        {
            this.AssociatedObject = associatedObject;

            // setup
            var checkbox = this.AssociatedObject as CheckBox;
            var binding = new Binding
            {
                Path = new PropertyPath("IsChecked"),
                Mode = BindingMode.TwoWay,
                Source = checkbox,
            };
            var property = NullableCheckboxBehavior.InternalStateProperty;
            checkbox.SetBinding(property, binding);
            checkbox.IsChecked = (bool?)this.InternalState;
        }

        public void Detach() { }

        private object InternalState
        {
            get { return (object)GetValue(InternalStateProperty); }
            set { SetValue(InternalStateProperty, value); }
        }
        public static readonly DependencyProperty InternalStateProperty =
            DependencyProperty.Register("InternalState", typeof(object),
            typeof(NullableCheckboxBehavior), new PropertyMetadata(null, InternalStateChanged));
        private static void InternalStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behaviors = (d as CheckBox).GetValue(Interaction.BehaviorsProperty) as BehaviorCollection;
            var behavior = behaviors.OfType<NullableCheckboxBehavior>().First();
            behavior.IsChecked = (bool?)e.NewValue;
        }

        public object IsChecked
        {
            get { return (object)GetValue(IsCheckedProperty); }
            set { SetValue(IsCheckedProperty, value); }
        }
        public static readonly DependencyProperty IsCheckedProperty =
            DependencyProperty.Register("IsChecked", typeof(object),
            typeof(NullableCheckboxBehavior), new PropertyMetadata(null, IsCheckedChanged));
        private static void IsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var checkbox = (d as NullableCheckboxBehavior).AssociatedObject as CheckBox;
            bool? newvalue = null;
            if (e.NewValue is bool?)
                newvalue = (bool?)e.NewValue;
            else if (e.NewValue != null)
            {
                bool newbool;
                if (!bool.TryParse(e.NewValue.ToString(), out newbool))
                    return;
                newvalue = newbool;
            }
            if (!checkbox.IsChecked.Equals(newvalue))
                checkbox.IsChecked = newvalue;
        }
    }
}
